GenieWorks, LLC
Introduction
SpotCheck is a language-based editor, or structure editor, that
"knows" the Java language. It is designed to help a novice Java
programmer produce correct code, without relying on confusing and un-timely
feedback from a compiler. SpotCheck helps you learn Java, or use parts
of the language you don't commonly use, by showing you exactly what's syntactically
possible at each juncture, and allowing you to choose. SpotCheck also identifies
common semantic errors (undefined names, type mismatches, etc.), and the
set of error checks available will grow with each release. This semantic
analysis is performed "incrementally", after each edit, giving
the programmer immediate feedback on errors. This and many other "convenience"features of SpotCheck will make even expert programmers find it an appealing
environment for creating Java code.
SpotCheck is not yet a complete programming environment, as it relies on
external support applications to compile Java source to class files. Nonetheless,
we have made every effort to make the compilation interface as transparent
as possible. As of this writing, SpotCheck has built-in AppleEvent interfaces
to Metrowerks' CodeWarrior and Sun's Mac JDK 1.0.2, with interfaces for
Symantec's Cafe and Natural Intelligence's Roaster planned.
The remainder of this README file functions as a limited User's Manual.
However, most of the information here is better presented in our new Tutorial
document. We highly recommend that you start there. There are still
a few topics that are explained in more detail here, if you should need
more information than the tutorial provides.
Scene Roots and the Browser
Scene roots are large sections of code that are elided, or abbreviated.
The bulk of the code is replaced with a "Go In" button. Simply
double-click on the button to see the rest. The entire "scene"you were just viewing will be replaced by the expanded class declaration,
method declaration or whatever. To return, use "Go Back" or "Go
Out" in the "Find" menu. "Go In" and "Go
Out" have keyboard equivalents that aren't shown in the menu, <command>-<down
arrow> and <command>-<up arrow>, respectively.
The "scene roots" form a course-grained hierarchy in the project.
The browser panes at the top of the window allow you to navigate this hierarchy
of packages, classes, etc. Single clicks suffice in the browser. Note that
there is a top-level "project scene" that has no browser entry
associated. You can access this scene using "Go To Project" in
the "Find" menu, repeated uses of <command>-<up arrow>,
or a single lt;command>-<shift>-<up arrow>.
Structure Editing
SpotCheck is first and foremost a structure editor, but it also
has a text-editing mode. The two modes are clearly differentiated visually,
but there is a way to maximize that differentiation. If you have a color
or grayscale monitor, make sure that your highlight color (in the Color
control panel) is NOT "Black & White". SpotCheck uses inverse
video (white text on black) for the selection in structure mode, and your
highlight color for the selection in text mode. Text mode is also distinguished
by an outlined box corresponding to the last structure selected. The sooner
you learn to distinguish which mode you are in, the happier you will be.
In structure mode, you edit the program using "point and click".
Portions of the program that have not been filled in yet are shown as "placeholders",
indicated by $-signs at each end. When you start SpotCheck, it opens the
Default stationery document, and asks you where you want to save your new
copy. Once you've saved the copy, you will see:
Select (click once on) "YourAppletAsApp", and hit the delete
key. You will now see:
There is a single placeholder here: "$the_name$". The small triangle
next to it indicates a popup menu... click and hold over the triangle,
and a menu of legal replacements for the placeholder appears. For this
placeholder, there is only one choice, "thisClassOrInterface".
When you select that choice, you will be dropped into text-editing mode
at that location, so you can type in an identifier. This happens in general,
whenever you select a choice that represents an identifier or literal value.
The popup menu for the current placeholder selection is also available
in the menu bar, as the "Construct" menu. The contents of this
menu change depending on what sort of placeholder is currently selected.
If the selection is not a placeholder, the "Construct" menu disappears.
The construct mode editing commands can be found in the Edit menu, with
their keyboard equivalents. There are, however, two shortcuts that are
not indicated in the menu. First, <return> is an alternative for
"Extend After", and is available in the same situations. This
is convenient for entering lists of statements, for example. Second, <space
bar> can be used to cycle through the possibilities at a particular
selection. This is most useful when the number of possibilities is small,
e.g. "public / private / protected". Nonetheless, you can use
it if you wish to explore the possibilities for $statement$. Note that
whatever syntax was originally present at the selection will be lost. Note
also that <space bar> will present dummy values for identifiers and
literals, and these are almost never useful.
Sprinkled throughout the code you will find little open circles. These
are simply "holes" for optional parts of the code that are currently
missing. Double-clicking on a "hole" will replace it with the
optional syntax, possibly just a placeholder. The <delete> key will
also have this effect on a "hole".
Normally you will move the structural selection by clicking (and possibly
dragging) with the mouse. A single click will select the nearest treenode
(going "up" the tree toward the root) whose "unparse area"includes the click point; that is, the "smallest" subtree containing
the click. Click and drag will select the smallest subtree that includes
both the start and end points of the drag. If you hold down the option
key while you drag, the selection will remain the smallest one containing
the current mouse point. This is a convenient way to familiarize yourself
with the structure of the abstract syntax tree.
You can also "navigate" using the arrow keys. The arrow keys
provide screen-oriented up-down-left-right navigation. If modified with
the <option> key, they provide navigation through the abstract syntax
tree:
option-left-arrow "go left to sibling"
option-right-arrow "go right to sibling"
option-up-arrow "go to parent"
option-down-arrow "go to first son"
The option-arrow keys are particularly useful when you can't seem to select
what you want with the mouse. If you can't get it with the arrow keys,
then you are attempting to select a chunk of syntax that is not represented
as a single tree node (or range of list members), which is not possible
in structure mode.
The arrow keys can also be modified with the <shift> key, to add
to the current selection. The resultant selection will be the smallest
that contains both the starting point and the item that would have been
selected by the un-shifted arrow key.
There is one additional shortcut for local tree navigation: the <tab>key takes you to the next "choice point", the next structural
selection that can be deleted or replaced. In technical terms, this basically
amounts to a pre-order traversal of the tree. In practical terms, it's
a more useful alternative to "option right arrow", which cannot
fill the same need without the assistance of "option up-arrow"and "option-down-arrow". It's also useful in that it stops at
"holes", which will be skipped by <command>-J, "go
to next placeholder". You will find that you can do quite a bit of
editing using simply two keys, <tab> and <space bar>, subject
to the limitations of the latter discussed above.
Text Editing
When you are in text-editing mode, the current structural selection is
surrounded by a box, and within that box is editable text (with its own
selection or "I-bar" cursor). To cancel text-editing mode, type
<command>-<period>... the program will remain unchanged. To
leave text-editing mode normally (causing the new text to be parsed in
context), type <enter>, <tab>, or <command>-T, or click
once outside of the text edit box anywhere that the "+" cursor
shows. Many users find <tab> to be the most convenient, and even
intuitive, since it effectively "goes to the next entry field".
You can enter text-edit mode on any selection using <command>-T ("Edit
as Text" in the "Edit" menu), or <enter>. You can
also accomplish this simply by starting to type over a placeholder. (This
will work for any selection, if your editing preference is set for this
behavior. Note that the text of the selection will be replaced with your
first keystroke.) Finally, double-clicking on most selections will enter
text-editing mode. The exceptions are scene roots, described below, and
"read-only" syntax, such as the package statement shown at the
beginning of each .java file.
SpotCheck's parser is fairly clever, and is able to parse partial input
as long as there is no error. You can take advantage of this behavior to
accelerate entry of your code. For instance, if your current selection
is a statement placeholder, you may simply type "for", followed
by <tab> or <enter>, and an entire for-statement will appear,
with placeholders for the unspecified pieces. At this point, the structure
selection will be the first placeholder in the for-statement, so you can
immediately type "int i=0", or whatever. Of course, you can just
as easily type in "for( int i=0;" <tab>, and the results
will be the same.
The parser will also accept placeholders in input text. In fact, it will
accept any string of text between two '$' characters... even "$$"is allowed. Any such placeholder token can "stand in" wherever
any kind of placeholder is allowed. This is usually an advantage, but it
can also cause problems for partial parsing. As an illustration, consider
the partial input, "$XXX$", typed on a statement placeholder.
There are several possible syntactic constructs that can begin with a placeholder
in this context, and the parser must arbitrarily select one. That's OK,
as long as the choice made is the one you intended, but it's inconvenient
otherwise. "Undo" comes in handy here.
SpotCheck's parser will rearrange some array declarations. SpotCheck displays
array variable declarations with the brackets next to the type, rather
than using the old C/C++ style:
"int[][] anArray" versus "int anArray[][]"
However, SpotCheck's parser will accept the old style. If multiple declarators
appear separated by commas, with differing numbers of trailing "[]"pairs, SpotCheck will create additional variable declaration lines as needed,
collecting all variables with the same array "depth" in one declaration.
Semantic Analysis and Error Tags
After each user editing operation, SpotCheck will incrementally update
its "database" of semantic information. The most visible effect
of this update will be the appearance or disappearance of "error tags"or "blobs" in the code. A blob is displayed as a red (option-8),
and signifies that the indicated piece of code is in violation of the Java
language specification. In short, SpotCheck is performing many of the checks
that the Java compiler will perform eventually, but SpotCheck is performing
them immediately.
This is not to say that SpotCheck is an incremental compiler . No
code is being generated. When all the semantic tests have been implemented
(only a few are, as yet), any piece of code that has no blobs present will
pass the compilers checks with flying colors. Effectively, the Java compiler
will simply be performing code generation.
Blobs are not simply inert visual noise; double-clicking on a blob will
bring up the error dialog, with an error message displayed within. Eventually,
we intend to provide much more information in the error dialog, including
"live" URLs to the language specification, online documentation,
or tutorials, and even options to apply automatic "fixes" to
common errors.
Blobs are also useful as "bookmarks" for incomplete code, a way
to let SpotCheck remember "what I haven't done yet". The most
common blob is the "undeclared identifier" error tag, which is
particularly useful in this regard.
As you might imagine, error tags are not the only use for the semantic
information maintained by SpotCheck. At any identifier reference site,
you can use "Go To Declaration" (in the "Find" menu)
to navigate directly to the declaration site for that identifier. Of course,
that operation will be unavailable if the identifier is not declared, or
if some other error prevents it from being bound to a declaration site.
(E.g., in " foo .bar", since "foo" is not declared,
"bar" cannot be looked up at all.) Also in the "Find"menu is the "Change Decl & Refs" command, which allows you
to simultaneously change an identifier declaration and all the identifier
reference sites currently bound to it. Note that some reference sites might
not stay bound after the change, if there is an existing declaration
with the same name that masks the renamed declaration.
Package Libraries
"Package
java" is a package library document , and must be present in
the same folder as the SpotCheck application. Package library documents
and normal SpotCheck project documents use exactly the same format
on disk, but package library documents are displayed differently and do
not allow compilation. They exist merely to provide a semantic infrastructure
for your projects. As such, they need not include any executable code,
nor private members.
SpotCheck supports package and import semantics exactly as described by
the Java language specification. An imported package can be found in any
open package library document, or in the document containing the importing
.java file. Imported packages are looked up by name, starting with top-level
names. Note that any SpotCheck project document can contain named packages
as well as .java files that belong to the unnamed, "default"package. In SpotCheck, a given .java file is a member of a given package
by virtue of being physically contained within the package. Use the "Go
To Project" command to see how packages and .java files are organized
in a SpotCheck project document. Note also that "import p1.p2.C3"will work only if both "package p1" and "package
p1.p2" are defined. Top-level packages like "p1" need not
contain any .java files, but they must exist in some open SpotCheck document.
SpotCheck automatically opens the "package java" library document
on each startup, and it is not closed until SpotCheck quits again.
This document contains version 1.0.2 of the standard API
classes, including packages java.lang, java.awt, and java.applet, and the
rest. You should never move or rename the document so that SpotCheck won't find it
on startup . Note also that "package java" is a very large
document, but it is hardly ever read into memory in its entirety.
Although SpotCheck is designed to support dependencies on (imports from)
multiple package library documents, that mechanism is not yet operative
as of this writing. As such, if your project document needs to import a
class from some package other than those found in "package java",
you have two options, neither of which are entirely satisfactory. First,
you can simply ignore the blobs that are present because SpotCheck cannot
find the package you are importing. The problem here, of course, is knowing
which blobs are due to the missing package and are therefore safe to ignore.
As an alternative, you can add the appropriate named packages, with whatever
class, interface, and member declarations your project requires, within
your project document . If you have included all the necessary declarations,
there should be no unnecessary blobs. However, when you compile your project,
SpotCheck will generate .java files for the library packages you've defined,
and will include those files in the compilation.
Compiling and Executing
The "Project" menu is largely self-explanatory, but there are
a couple of things that must be explained about the compilation interface.
Most important is the basic organization of a SpotCheck project document.
Each such document can contain many ".java file" components.
These are not actually separate files; all the information is contained
within the same project document. Nonetheless, the external compiler applications
require individual text files, so SpotCheck generates these text files
as needed.
When you execute one of the compile commands ("Build and Run Project",
"Compile Project", or "Compile .java File"), SpotCheck
will first make sure that all the changed ".java file" components
of your project will be written to disk as individual text files. SpotCheck
remembers which of the internal "files" have been changed since
the last compile, and avoids re-creating disk versions of unchanged .java
files. You can force all .java files to be recreated on disk using the
"Touch All Files" command before compiling.
Using CodeWarrior to Compile
CodeWarrior has the curious feature that it requires the Apple Script system
extension to be loaded before it will respond to AppleEvents. If SpotCheck
can find and launch CodeWarrior, but can't seem to make it do anything,
you may need to install Apple Script and restart your Mac.
We have tried to isolate SpotCheck users from the complexities of using
CodeWarrior as much as possible. In doing so, we have chosen a particular
set of project settings for CodeWarrior Java projects created automatically
by SpotCheck. You may find that these settings are not quite what you need.
If so, you can simply make the necessary adjustments after SpotCheck has
directed CodeWarrior to create the project. (SpotCheck does this automatically,
the first time you compile your project.)
SpotCheck's default project document is for an Applet subclass that also
has a static "main" method, allowing it to be run as a standalone
application. The CodeWarrior project settings have been tuned for this
default, creating a "Runable Zip File". SpotCheck will set the
"File Name" and "Main Class" automatically, using the
name of your SpotCheck project document minus the ".spot" extension.
The name of the CodeWarrior project document itself is set according to
a similar convention; if you change this name by hand, SpotCheck will be
unable to find the project to compile.
After SpotCheck sends the "compile" AppleEvent to CodeWarrior,
it waits for a response. The response event either will indicate success,
or will contain a list of error messages. In the latter case, SpotCheck
unpacks these and provides a simple "compiler error dialog" for
browsing through the errors, selecting the closest bit of syntax for display.
You can close the compiler error dialog, and reopen it with "Show
Errors".
SpotCheck cannot tell (presently) if you have edited the on-disk .java
text files, for example if you used CodeWarrior to browse through and fix
any errors reported after an attempted compilation. As such, unless you
remember to make the same changes within the SpotCheck project document,
your changes will be lost the next time SpotCheck regenerates the .java
text files. We recommend making all your changes within SpotCheck.
Another problem arises if CodeWarrior's "Message Window" has
the lower pane open, showing the code for each error message listed in
the upper pane. If that is the case, the .java text file being displayed
is open in CodeWarrior, and SpotCheck will be unable to overwrite that
file on the next compile. If you toggle the lower pane closed (using the
little triangle on the left), there will be no problem.
Compiling with Sun's JDK
JDK has no project documents, so compilation is a good deal simpler that
it is using CodeWarrior. There are only a few wrinkles. First, if your
project contains several .java files, they often need to be compiled at
the same time. Rather than attempting to be too clever just yet, SpotCheck
simply simulates dragging dropping all your .java files onto the
Java Compiler, regardless of whether you indicated "Compile Project"or "Compile .java File".
The "Build & Run Project" command does not function as advertised...
it will only run the project. You must compile the project explicitly before
executing it.
If you use JDK, you may have discovered the settings that make the compiler
run faster. We find using the Java Compiler much more pleasant if we disable
threaded compiles, debugger info, and code optimization. See the "Properties..."command in the "File" menu of the Java Compiler application.
Be sure to hit the "OK" button to make your changes permanent.